package main

import (
	"database/sql"
	"fmt"
	"log"
	"net/http"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
	_ "github.com/go-sql-driver/mysql"
)

// App 应用结构
type App struct {
	ID                 int         `json:"id"`
	Name               string      `json:"name"`
	Description        string      `json:"description"`
	Icon               string      `json:"icon"`
	CoverImage         string      `json:"coverImage"`
	Category           string      `json:"category"`
	Rating             float32     `json:"rating"`
	RatingDistribution map[int]int `json:"ratingDistribution"`
	Downloads          string      `json:"downloads"`
	UpdateDate         string      `json:"updateDate"`
	Platform           string      `json:"platform"`
	Size               string      `json:"size"`
	Version            string      `json:"version"`
	PriceType          string      `json:"priceType"` // free, inapp
	Screenshots        []string    `json:"screenshots"`
	Features           []Feature   `json:"features"`
	Reviews            []Review    `json:"reviews"`
}

// AppLink 应用下载链接结构
type AppLink struct {
	ID           int    `json:"id"`
	AppID        int    `json:"appId"`
	Platform     string `json:"platform"`
	DownloadURL  string `json:"downloadUrl"`
	Version      string `json:"version"`
	ReleaseNotes string `json:"releaseNotes,omitempty"`
	ReleaseDate  string `json:"releaseDate"`
	IsActive     bool   `json:"isActive"`
}

// Feature 应用功能特点
type Feature struct {
	Title       string `json:"title"`
	Description string `json:"description"`
}

// Review 用户评论
type Review struct {
	ID       int    `json:"id"`
	Username string `json:"username"`
	Avatar   string `json:"avatar"`
	Rating   int    `json:"rating"`
	Content  string `json:"content"`
	Date     string `json:"date"`
	AppID    int    `json:"appId"`
}

// 数据库连接
var db *sql.DB

func main() {
	// 初始化数据库连接
	var err error
	dsn := "appstore:Appstore778!@tcp(localhost:3306)/appstore?parseTime=true"
	db, err = sql.Open("mysql", dsn)
	if err != nil {
		log.Fatal(err)
	}

	// 测试数据库连接
	err = db.Ping()
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("Connected to database!")

	// 创建默认路由引擎
	r := gin.Default()

	// 静态文件服务
	r.Static("/static", "./static")

	// 路由
	r.GET("/", func(c *gin.Context) {
		c.File("templates/index.html")
	})

	r.GET("/detail", func(c *gin.Context) {
		c.File("templates/detail.html")
	})

	// API路由
	r.GET("/api/apps", getApps)
	r.GET("/api/apps/:id", getApp)
	r.GET("/api/app/link", getAppLink)
	r.POST("/api/apps", createApp)
	r.PUT("/api/apps/:id", updateApp)
	r.DELETE("/api/apps/:id", deleteApp)

	// 启动服务器
	fmt.Println("Server started on port 9766")
	log.Fatal(r.Run(":9766"))
}

// 获取应用列表
func getApps(c *gin.Context) {
	var apps []App

	// 查询应用基本信息
	query := `
		SELECT 
			id, name, description, icon, cover_image, category, rating, downloads, 
			DATE_FORMAT(update_date, '%Y-%m-%d') as update_date, platform, size, price_type
		FROM apps
		ORDER BY rating DESC
	`

	rows, err := db.Query(query)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	defer rows.Close()

	for rows.Next() {
		var app App
		err := rows.Scan(
			&app.ID, &app.Name, &app.Description, &app.Icon, &app.CoverImage,
			&app.Category, &app.Rating, &app.Downloads, &app.UpdateDate,
			&app.Platform, &app.Size, &app.PriceType,
		)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}

		// 获取评分分布
		app.RatingDistribution = make(map[int]int)
		ratingRows, err := db.Query(`
			SELECT rating, COUNT(*) as count
			FROM reviews
			WHERE app_id = ?
			GROUP BY rating
		`, app.ID)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
		defer ratingRows.Close()

		for ratingRows.Next() {
			var rating, count int
			err := ratingRows.Scan(&rating, &count)
			if err != nil {
				c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
				return
			}
			app.RatingDistribution[rating] = count
		}

		// 计算总评分
		totalReviews := 0
		for _, count := range app.RatingDistribution {
			totalReviews += count
		}

		// 设置默认评分分布
		if totalReviews == 0 {
			app.RatingDistribution = map[int]int{5: 100, 4: 0, 3: 0, 2: 0, 1: 0}
		}

		apps = append(apps, app)
	}

	c.JSON(http.StatusOK, apps)
}

// 获取单个应用详情
func getApp(c *gin.Context) {
	// 获取URL参数
	idStr := c.Param("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid app ID"})
		return
	}

	// 查询应用基本信息
	var app App
	query := `
		SELECT 
			id, name, description, icon, cover_image, category, rating, downloads, 
			DATE_FORMAT(update_date, '%Y-%m-%d') as update_date, platform, size, version, price_type
		FROM apps
		WHERE id = ?
	`

	err = db.QueryRow(query, id).Scan(
		&app.ID, &app.Name, &app.Description, &app.Icon, &app.CoverImage,
		&app.Category, &app.Rating, &app.Downloads, &app.UpdateDate,
		&app.Platform, &app.Size, &app.Version, &app.PriceType,
	)

	if err != nil {
		if err == sql.ErrNoRows {
			c.JSON(http.StatusNotFound, gin.H{"error": "App not found"})
		} else {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		}
		return
	}

	// 获取评分分布
	app.RatingDistribution = make(map[int]int)
	ratingRows, err := db.Query(`
		SELECT rating, COUNT(*) as count
		FROM reviews
		WHERE app_id = ?
		GROUP BY rating
	`, app.ID)

	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	defer ratingRows.Close()

	totalReviews := 0
	for ratingRows.Next() {
		var rating, count int
		err := ratingRows.Scan(&rating, &count)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
		app.RatingDistribution[rating] = count
		totalReviews += count
	}

	// 设置默认评分分布
	if totalReviews == 0 {
		app.RatingDistribution = map[int]int{5: 100, 4: 0, 3: 0, 2: 0, 1: 0}
	}

	// 获取截图
	screenshotRows, err := db.Query(`
		SELECT image_url
		FROM screenshots
		WHERE app_id = ?
		ORDER BY id ASC
	`, app.ID)

	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	defer screenshotRows.Close()

	app.Screenshots = []string{}
	for screenshotRows.Next() {
		var imageURL string
		err := screenshotRows.Scan(&imageURL)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
		app.Screenshots = append(app.Screenshots, imageURL)
	}

	// 获取功能特点
	featureRows, err := db.Query(`
		SELECT title, description
		FROM features
		WHERE app_id = ?
		ORDER BY id ASC
	`, app.ID)

	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	defer featureRows.Close()

	app.Features = []Feature{}
	for featureRows.Next() {
		var feature Feature
		err := featureRows.Scan(&feature.Title, &feature.Description)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
		app.Features = append(app.Features, feature)
	}

	// 获取评论
	reviewRows, err := db.Query(`
		SELECT id, username, avatar, rating, content, DATE_FORMAT(create_time, '%Y-%m-%d') as date, app_id
		FROM reviews
		WHERE app_id = ?
		ORDER BY create_time DESC
		LIMIT 3
	`, app.ID)

	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	defer reviewRows.Close()

	app.Reviews = []Review{}
	for reviewRows.Next() {
		var review Review
		err := reviewRows.Scan(
			&review.ID, &review.Username, &review.Avatar, &review.Rating,
			&review.Content, &review.Date, &review.AppID,
		)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
		app.Reviews = append(app.Reviews, review)
	}

	c.JSON(http.StatusOK, app)
}

// 获取应用的所有下载链接
func getAppLink(c *gin.Context) {
	// 获取URL参数
	appIDStr := c.Query("id")
	os := c.Query("os")
	appID, err := strconv.Atoi(appIDStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid app ID"})
		return
	}

	// 查询下载链接列表
	var links []AppLink
	query := `
        SELECT 
            id, app_id, platform, download_url, 
            version, release_notes, DATE_FORMAT(release_date, '%Y-%m-%d') as release_date,
            is_active
        FROM download_links
        WHERE app_id = ? AND is_active = 1 AND platform = ?
        ORDER BY release_date DESC
    `

	rows, err := db.Query(query, appID, os)
	if err != nil {
		print(err.Error())
		c.JSON(http.StatusOK, map[string]any{
			"msg":  "应用不存在",
			"code": 201,
		})
		return
	}
	defer rows.Close()

	for rows.Next() {
		var link AppLink
		if err := rows.Scan(
			&link.ID, &link.AppID, &link.Platform, &link.DownloadURL,
			&link.Version,
			&link.ReleaseNotes, &link.ReleaseDate, &link.IsActive,
		); err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
		links = append(links, link)
	}

	if links == nil {
		c.JSON(http.StatusOK, map[string]any{
			"msg":  "应用不存在",
			"code": 201,
		})
		return
	}
	c.JSON(http.StatusOK, map[string]any{
		"list": links,
		"code": 200,
		"msg":  "ok",
	})
}

// 创建应用
func createApp(c *gin.Context) {
	var app App
	if err := c.ShouldBindJSON(&app); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 开始事务
	tx, err := db.Begin()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	defer func() {
		if p := recover(); p != nil {
			// 回滚事务
			tx.Rollback()
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Transaction failed"})
			panic(p)
		} else if err != nil {
			tx.Rollback()
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		} else {
			err = tx.Commit()
			if err != nil {
				c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			}
		}
	}()

	// 插入应用基本信息
	result, err := tx.Exec(`
		INSERT INTO apps (
			name, description, icon, cover_image, category, rating, downloads, 
			update_date, platform, size, version, price_type
		) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
	`,
		app.Name, app.Description, app.Icon, app.CoverImage, app.Category,
		app.Rating, app.Downloads, time.Now(), app.Platform, app.Size,
		app.Version, app.PriceType)

	if err != nil {
		return
	}

	// 获取插入的应用ID
	appID, err := result.LastInsertId()
	if err != nil {
		return
	}

	// 插入截图
	for _, screenshot := range app.Screenshots {
		_, err := tx.Exec(`
			INSERT INTO screenshots (app_id, image_url) VALUES (?, ?)
		`, appID, screenshot)
		if err != nil {
			return
		}
	}

	// 插入功能特点
	for _, feature := range app.Features {
		_, err := tx.Exec(`
			INSERT INTO features (app_id, title, description) VALUES (?, ?, ?)
		`, appID, feature.Title, feature.Description)
		if err != nil {
			return
		}
	}

	c.JSON(http.StatusCreated, gin.H{"message": "App created successfully", "id": appID})
}

// 更新应用
func updateApp(c *gin.Context) {
	// 获取URL参数
	idStr := c.Param("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid app ID"})
		return
	}

	// 解析请求体
	var app App
	if err := c.ShouldBindJSON(&app); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 开始事务
	tx, err := db.Begin()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	defer func() {
		if p := recover(); p != nil {
			// 回滚事务
			tx.Rollback()
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Transaction failed"})
			panic(p)
		} else if err != nil {
			tx.Rollback()
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		} else {
			err = tx.Commit()
			if err != nil {
				c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			}
		}
	}()

	// 更新应用基本信息
	_, err = tx.Exec(`
		UPDATE apps 
		SET name = ?, description = ?, icon = ?, cover_image = ?, category = ?, 
		    rating = ?, downloads = ?, update_date = ?, platform = ?, size = ?, 
		    version = ?, price_type = ?
		WHERE id = ?
	`,
		app.Name, app.Description, app.Icon, app.CoverImage, app.Category,
		app.Rating, app.Downloads, time.Now(), app.Platform, app.Size,
		app.Version, app.PriceType, id)

	if err != nil {
		return
	}

	// 删除旧的截图
	_, err = tx.Exec(`DELETE FROM screenshots WHERE app_id = ?`, id)
	if err != nil {
		return
	}

	// 插入新的截图
	for _, screenshot := range app.Screenshots {
		_, err := tx.Exec(`
			INSERT INTO screenshots (app_id, image_url) VALUES (?, ?)
		`, id, screenshot)
		if err != nil {
			return
		}
	}

	// 删除旧的功能特点
	_, err = tx.Exec(`DELETE FROM features WHERE app_id = ?`, id)
	if err != nil {
		return
	}

	// 插入新的功能特点
	for _, feature := range app.Features {
		_, err := tx.Exec(`
			INSERT INTO features (app_id, title, description) VALUES (?, ?, ?)
		`, id, feature.Title, feature.Description)
		if err != nil {
			return
		}
	}

	c.JSON(http.StatusOK, gin.H{"message": "App updated successfully"})
}

// 删除应用
func deleteApp(c *gin.Context) {
	// 获取URL参数
	idStr := c.Param("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid app ID"})
		return
	}

	// 开始事务
	tx, err := db.Begin()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	defer func() {
		if p := recover(); p != nil {
			// 回滚事务
			tx.Rollback()
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Transaction failed"})
			panic(p)
		} else if err != nil {
			tx.Rollback()
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		} else {
			err = tx.Commit()
			if err != nil {
				c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			}
		}
	}()

	// 删除相关评论
	_, err = tx.Exec(`DELETE FROM reviews WHERE app_id = ?`, id)
	if err != nil {
		return
	}

	// 删除截图
	_, err = tx.Exec(`DELETE FROM screenshots WHERE app_id = ?`, id)
	if err != nil {
		return
	}

	// 删除功能特点
	_, err = tx.Exec(`DELETE FROM features WHERE app_id = ?`, id)
	if err != nil {
		return
	}

	// 删除应用
	_, err = tx.Exec(`DELETE FROM apps WHERE id = ?`, id)
	if err != nil {
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "App deleted successfully"})
}
